﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MIPS_Simulator
{
    public class Wires
    {

        #region Control Wires
        public static int RegDst;
        public static int Jump;
        public static int BranchIfEqual;
        public static int BranchIfNotEqual;
        public static int JumpAndLink;
        public static int JR;
        public static int MemRead;
        public static int MemToReg;
        public static int ALUOP;
        public static int MemWrite;
        public static int ALUSrc;
        public static int RegWrite;
        #endregion 

        #region Instruction Memory Wires
        public static short OPCODE;
        public static short RegSource1;
        public static short RegSource2;
        public static short RegDestination;
        public static short RegAddress;
        #endregion 

        #region ALU Wires
        public static long ALURead1;
        public static long ALURead2;
        public static int ALUControl;
        public static int ALUFunction;
        public static long ALUResult;
        public static long Zero;
        #endregion 
        public static string immediate;
        #region Memory Wires
        public static int WriteData;
        public static int ReadData;
        #endregion

        #region Program Counter Wires
        public static short PCAddress;
        public static short JumpTarget;
        public static short JumpAddress;
        public static short AdderResult;
        public static short ALU2Result;
        public static int rs;
        public static int Rs
        {
            get 
            {
                return rs;
            }
            set 
            {
                rs=value;
            }
        }
        public static int rt;
        public static int Rt
        {
            get
            {
                return rt;
            }
            set
            {
                rt = value;
            }
        }
       
        public static int rd;
        public static int Rd
        {
            get
            {
                return rd;
            }
            set
            {
                rd = value;
            }
        }
       

        #endregion 

        #region Setter Methods

        public static void Add()
        {
            RegWrite = 1;
            RegDst = 1;
            ALUOP = 10;
            ALUFunction = 100000;
            ALUControl = 0010;
        }

        public static void Sub()
        {
            RegDst = 1;
            RegWrite = 1;
            ALUOP = 10;
            ALUFunction = 10010;
            ALUControl = 0110;
        }

        public static void And()
        {
            RegWrite = 1;
            RegDst = 1;
            ALUOP = 10;
            ALUFunction = 100100;
            ALUControl = 0000;
        }

        public static void Or()
        {
            RegDst = 1;
            RegWrite = 1;
            ALUOP = 10;
            ALUFunction = 100101;
            ALUControl = 0001;
        }
        #endregion

        #region Mux,Sign extend, Shift2,ShiftLeft
        public static string Mux(long input0, int input1, int flag)
        {
            if (flag==0)
                return input0.ToString();
            else
                return input1.ToString();
        }

        public static string SignExtend(string input)
        {
            if (input[0] == '1')
                return "1111111111111111" + input;
            else
                return "0000000000000000" + input;
        }
        public static string ShiftLeft2(string input)
        {
            return input.Substring(2, input.Length - 2) + "00";
        }

        #endregion
        #region ALU wires
        public static string aluZero;
        public static string aluResult;

        public static string AluOperand1()
        {
            return registerReadData1;
        }

        public static string AluOperand2()
        {
            return Mux((long)Int32.Parse(registerReadData2), Int32.Parse(SignExtend(immediate)), ALUSrc);
        }

        public static short AluOpcode()
        {
            return OPCODE;
        }

        public static int AluFunction()
        {
            return ALUFunction;
        }
        #endregion
        #region branch
        public static string branchAddResult;


        public static string BranchAddOperand2()
        {
            return ShiftLeft2(SignExtend(immediate));
        }


        public static string BranchAddOperand()
        {
            return ShiftLeft2(SignExtend(immediate));
        }
        #endregion
        #region registers

        public static string registerReadData1;
        public static string registerReadData2;


        public static int ReadRegister1()
        {
            return rs;
        }
        public static int ReadRegister2()
        {
            return rt;
        }
        public static int WriteRegister()
        {
            return Int32.Parse(Mux(rt, rd, RegDst));
        }

        public static int RegisterWriteData()
        {
            return Int32.Parse(Mux(ALUResult, MemRead, MemToReg));
        }

        public static int RegisterWriteFlag()
        {
            return RegWrite;
        } 
#endregion
    }

}